<!-- 本DEMO假设用户用PoLine去创建到货单，创建到货单的时候，需要指定PoLineId和到货单号，确保指定的PoLineId所属的PoId相同 -->
<template>
  <q-page class="q-pa-md">
    <div class="q-pb-md text-h5">简单过滤下拉DEMO <span class="text-subtitle1">用于演示“购物车”组件的功能(内部使用)</span></div>
    <div class="shadow-2 q-pa-sm">
      <p>
        购物车是将一些要提交的条目选中到一个集合中，然后打开对话框进行确认，提交，这么一种模式。它能实现跨页选择，这是它最主要的功能，
        另外就是提供了一个确认界面，在确认界面上可以取消选择和修改待提交数量。
      </p>
      <p>
        老实说这个购物车功能做得不是很好，虽然能用，但用起来有些繁琐，设计这个功能花费了很多时间，主要是验证这块，购物车的验证分成两个部分，
        一个是slot里的表单的验证，一个是明细行的qty的验证，前者用vuelidate没问题，后者则不太适合，所以干脆定义为自己验证，通过
        <code>validate-line-qty</code>传入一个验证方法，而插槽的验证完全就由其父组件(页面)负责，但购物车组件仍然需要知道验证成功与否，
        这是通过<code>validate-slot</code>传入的方法来获得验证结果的。当然了，验证并非必须，如果不传，则不会去验证它。
      </p>
    </div>
    <div class="shadow-2 q-mt-md">
      <q-table :columns="columnsInfo" :rows="$d.poLineListData" :hide-pagination="true"
        v-model:pagination="$d.paginationInfo"
        binary-state-sort color="primary" dense flat row-key="poLineId" separator="cell">
        <template v-slot:top="props">
          <div class="row q-gutter-sm">
            <shopping-cart btn-title="创建到货单" dlg-title="创建到货单" v-model:pending-items="$d.poLinesToCreateAsn"
              :columns-info="columnsInfoToCreateAsn" :disable-when-empty="true" @on-confirm="onCreateByPoLines"
              :working-state="$d.workingStateCreateAsn" v-model:server-error-message="$d.serverErrorMessageCreateAsn"
              qty-field-name="qty" id-field-name="poLineId" ref="shoppingCartCreateAsn" :validate-line-qty="validateAsnLineQty"
              :validate-slot="()=>v$.$validate()" @before-show="()=>v$.$reset()">
              <template v-slot:extra-form>
                <div class="row q-mt-sm">
                  <div class="col-xs-12 col-sm-8 col-md-6 col-lg-4">
                    <q-input :hide-bottom-space="true" :error-message="e$(v$.asnNoToCreate.$errors)"
                      :error="v$.asnNoToCreate.$error" :readonly="$d.workingStateCreateAsn"
                      @focus="ui.select" dense :maxlength="20" no-error-icon outlined square stack-label
                      v-model="$d.asnNoToCreate" placeholder="到货单号" autofocus />
                  </div>
                </div>
              </template>
            </shopping-cart>
            <q-btn color="primary" label="全选" @click="selectAllPoLines"></q-btn>
          </div>
          <q-space />
          <q-btn :icon="props.inFullscreen ? 'fullscreen_exit' : 'fullscreen'" :ripple="false"
            :title="props.inFullscreen ? '退出全屏' : '全屏显示'" @click="props.toggleFullscreen" dense flat />
        </template>
        <template v-slot:no-data>
          <div class="full-width items-center justify-center row">
            <q-icon name="error_outline" />
            无数据
          </div>
        </template>
        <!--操作列-->
        <template v-slot:body-cell-operation="props">
          <q-td :props="props" auto-width>
            <q-btn @click="addToListToCreateAsn(props.row)" class="btn-in-row" color="primary" dense label="到货"
              title="创建到货单" :disable="isPoLineSelected(props.row)" />
          </q-td>
        </template>
        <!-- 底部分页条 -->
        <template v-slot:bottom>
          <paging-bar :pageNo="$d.paginationInfo.page" :pageSize="$d.paginationInfo.rowsPerPage"
            :totalAmount="$d.poLineListData.length" @go-to-page="(pageNo)=>$d.paginationInfo.page=pageNo"
            @pagesize-changed="(pageSize)=>$d.paginationInfo.rowsPerPage=pageSize" :show-refresh-button="false"
            :restrict-input-page-no="true" />
        </template>
      </q-table>
    </div>
  </q-page>
</template>

<script lang="ts" setup>
import _ from 'lodash'
import {computed, reactive, ref} from 'vue'
import useVuelidate from '@vuelidate/core'

interface PoLine {
  poId: number
  poLineId: number
  skuId: number
  sku: string
  qtyExpected: number
  description: string
  qty?: number
}

let $d = reactive({
  asnNoToCreate: '',
  paginationInfo: {
    // 页码
    page: 1,
    // 每页多少条
    rowsPerPage: 15
  },
  // 用于测试的PoLine数据
  poLineListData: [
    {poId: 101, poLineId: 1001, skuId: 263, sku: 'AMD2X8654-Z1', qtyExpected: 16, description: '已带保费'},
    {poId: 101, poLineId: 1002, skuId: 264, sku: 'INTEL8626-A6', qtyExpected: 1000, description: ''},
    {poId: 101, poLineId: 1003, skuId: 265, sku: 'CYRIX8889-Z1', qtyExpected: 15, description: null},
    {poId: 101, poLineId: 1004, skuId: 266, sku: 'FYI286321-99', qtyExpected: 1, description: null},
    {poId: 101, poLineId: 1005, skuId: 270, sku: 'AA88888BBB22', qtyExpected: 180, description: 'AAAA. BBBB.'},
    {poId: 101, poLineId: 1006, skuId: 279, sku: 'BB11111AAA22', qtyExpected: 26, description: null},
    {poId: 101, poLineId: 1007, skuId: 286, sku: 'YOUYOUYOUXXX', qtyExpected: 33, description: null},

    {poId: 102, poLineId: 1008, skuId: 266, sku: 'FYI286321-99', qtyExpected: 40, description: ''},
    {poId: 102, poLineId: 1009, skuId: 265, sku: 'CYRIX8889-Z1', qtyExpected: 11, description: null},
    {poId: 102, poLineId: 1010, skuId: 263, sku: 'AMD2X8654-Z1', qtyExpected: 1, description: null},
    {poId: 102, poLineId: 1011, skuId: 270, sku: 'AA88888BBB22', qtyExpected: 2, description: null},
    {poId: 102, poLineId: 1012, skuId: 286, sku: 'YOUYOUYOUXXX', qtyExpected: 44, description: null},

    {poId: 103, poLineId: 1013, skuId: 263, sku: 'AMD2X8654-Z1', qtyExpected: 160, description: '描述'},
    {poId: 103, poLineId: 1014, skuId: 265, sku: 'CYRIX8889-Z1', qtyExpected: 120, description: '注意验收'},
    {poId: 103, poLineId: 1015, skuId: 270, sku: 'AA88888BBB22', qtyExpected: 10000, description: '东西不值钱'},
    {poId: 103, poLineId: 1016, skuId: 264, sku: 'INTEL8626-A6', qtyExpected: 50000, description: null},
    {poId: 103, poLineId: 1017, skuId: 286, sku: 'YOUYOUYOUXXX', qtyExpected: 46230, description: null},

    {poId: 104, poLineId: 1018, skuId: 270, sku: 'AA88888BBB22', qtyExpected: 100000, description: null},
    {poId: 104, poLineId: 1019, skuId: 266, sku: 'FYI286321-99', qtyExpected: 1000000, description: null},
    {poId: 104, poLineId: 1020, skuId: 286, sku: 'YOUYOUYOUXXX', qtyExpected: 5432123, description: '哈哈哈'},

    {poId: 105, poLineId: 1021, skuId: 270, sku: 'AA88888BBB22', qtyExpected: 11, description: null},
    {poId: 105, poLineId: 1022, skuId: 266, sku: 'FYI286321-99', qtyExpected: 26, description: null},
    {poId: 105, poLineId: 1023, skuId: 264, sku: 'INTEL8626-A6', qtyExpected: 33, description: 'A'},
    {poId: 105, poLineId: 1024, skuId: 263, sku: 'AMD2X8654-Z1', qtyExpected: 88, description: null},
    {poId: 105, poLineId: 1025, skuId: 265, sku: 'CYRIX8889-Z1', qtyExpected: 90, description: null},
    {poId: 105, poLineId: 1026, skuId: 286, sku: 'YOUYOUYOUXXX', qtyExpected: 99, description: '不知道写啥'}
  ] as PoLine[],
  // 购物车(创建ASN的PoLines),出错信息(banner展示)
  serverErrorMessageCreateAsn: '',
  // 购物车(创建ASN的PoLines),工作状态
  workingStateCreateAsn: false,
  // 购物车(创建ASN的PoLines)数据
  poLinesToCreateAsn: [] as PoLine[]
})
// 列参数
let columnsInfo = [
  {
    name: 'operation',
    label: '操作',
    field: 'operation',
    align: 'left'
  },
  {
    label: '采购单明细ID',
    name: 'poLineId',
    field: 'poLineId',
    sortable: true,
    align: 'left'
  },
  {
    label: '采购单ID',
    name: 'poId',
    field: 'poId',
    sortable: true,
    align: 'left'
  },
  {
    label: '物料ID',
    name: 'skuId',
    field: 'skuId',
    sortable: true,
    align: 'left'
  },
  {
    label: '物料',
    name: 'sku',
    field: 'sku',
    sortable: true,
    align: 'left'
  },
  {
    label: '预计到货量',
    name: 'qtyExpected',
    field: 'qtyExpected',
    align: 'left'
  },
  {
    label: '描述',
    name: 'description',
    field: 'description',
    align: 'left'
  }
]
// 购物车(创建ASN的PoLines)列参数
let columnsInfoToCreateAsn = [
  {
    label: '到货数量',
    name: 'qty',
    field: 'qty',
    align: 'left'
  },
  {
    label: '预计数量',
    name: 'qtyExpected',
    field: 'qtyExpected',
    sortable: true,
    align: 'left'
  },
  {
    label: '采购单明细ID',
    name: 'id',
    field: 'poLineId',
    sortable: true,
    align: 'left'
  },
  {
    label: '采购单ID',
    name: 'poId',
    field: 'poId',
    sortable: true,
    align: 'left'
  },
  {
    label: '料号',
    name: 'sku',
    field: 'sku',
    sortable: true,
    align: 'left'
  },
  {
    label: '描述',
    name: 'description',
    field: 'description',
    align: 'left'
  }
]

let addToListToCreateAsn = function (poLine: PoLine) {
  poLine.qty = poLine.qtyExpected
  $d.poLinesToCreateAsn.push(poLine)
}

let isPoLineSelected = function (poLine: PoLine) {
  return _.findIndex($d.poLinesToCreateAsn, {poLineId: poLine.poLineId}) !== -1
}

let selectAllPoLines = function () {
  $d.poLinesToCreateAsn = _.clone($d.poLineListData)
  _.forEach($d.poLinesToCreateAsn, (poLine) => {
    poLine.qty = poLine.qtyExpected // 给qty赋初值
  })
}

const validators = $f.validators

const rules = {
  asnNoToCreate: {
    required: validators.required
  }
}

const v$ = useVuelidate(rules, computed(() => $d), {$autoDirty: true})

let shoppingCartCreateAsn = ref()

let onCreateByPoLines = function () {
  let poNumTest = _.uniqBy($d.poLinesToCreateAsn, 'poId')
  if (poNumTest.length > 1) {
    void $f.ui.messageBox({
      caption: '出错了',
      text: '所选条目中存在不同的采购单ID，无法创建到货单',
      icon: 'Error',
      buttons: 'Close'
    })
    return
  }

  console.log('要提交的购物车的内容:')
  console.log($d.asnNoToCreate)
  console.log($d.poLinesToCreateAsn)

  // 模拟提交动作
  $d.serverErrorMessageCreateAsn = ''
  $d.workingStateCreateAsn = true
  setTimeout(() => {
    if ($d.asnNoToCreate === 'error') {
      // 出错
      $d.serverErrorMessageCreateAsn = '服务器返回一个错误(模拟)'
    } else {
      // 成功
      void $f.ui.messageBox({
        caption: '处理成功',
        text: '成功创建了到货单: ' + $d.asnNoToCreate,
        icon: 'Succeeded',
        buttons: 'Close'
      }).then(() => {
        shoppingCartCreateAsn.value.closeDlg()
        // 清空所选、单号
        $d.poLinesToCreateAsn = []
        $d.asnNoToCreate = ''
        // 刷新列表
      })
    }
    $d.workingStateCreateAsn = false
  }, 2000)
}

const validateAsnLineQty  = (value: string, lineIdx: number) => {
  if(!$f.valFuncs.isValidDecimal(value, 0)){
    return '请填入整数'
  }
  let qty = _.toNumber(value);
  if(qty> $d.poLinesToCreateAsn[lineIdx].qtyExpected){
    return '不可大于' + $d.poLinesToCreateAsn[lineIdx].qtyExpected.toString()
  }
  return ''
}

const ui = $f.ui
const e$ = $f.getFieldErrStr
</script>

<style lang="sass" scoped>
code
  background-color: #EEE

p
  margin: 5px
</style>
